use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};

use super::Desc;

#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JsErrDetailReq {
    start_time: String,
    end_time: String,
    error_msg_md5: String,
    error_stack_md5: String,
    app_version: String,
    sdk_version: String,
    os_name: OsName,
    client_version: String,
    openid: String,
    offset: u32,
    limit: u32,
    desc: Desc,
}

impl JsErrDetailReq {
    pub fn builder() -> JsErrDetailReqBuilder {
        JsErrDetailReqBuilder::default()
    }
}

#[derive(Clone, Debug, Default, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum OsName {
    #[default]
    All = 0,
    Andriod = 1,
    IOS = 2,
    Other = 3,
}

#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsErrDetailRes {
    pub data: Vec<JsErrDetailDataItem>,
    pub total_count: u32,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsErrDetailDataItem {
    pub count: String,
    pub skd_version: String,
    pub client_version: String,
    pub error_stack_md: String,
    pub time_stamp: String,
    pub app_version: String,
    pub error_msg_md5: String,
    pub error_msg: String,
    pub error_stack: String,
    pub ds: String,
    pub os_name: OsName,
    pub openid: String,
    pub pluginversion: String,
    pub app_id: String,
    pub device_mode: String,
    pub source: String,
    pub route: String,
    pub nickname: String,
}

#[derive(Clone, Debug, Default)]
pub struct JsErrDetailReqBuilder {
    start_time: String,
    end_time: String,
    error_msg_md5: String,
    error_stack_md5: String,
    app_version: String,
    sdk_version: String,
    os_name: OsName,
    client_version: String,
    openid: String,
    offset: u32,
    limit: u32,
    desc: Desc,
}

impl JsErrDetailReqBuilder {
    pub fn start_time<T>(mut self, time: T) -> Self
    where
        T: AsRef<str>,
    {
        self.start_time = time.as_ref().to_owned();
        self
    }

    pub fn end_time<T>(mut self, time: T) -> Self
    where
        T: AsRef<str>,
    {
        self.end_time = time.as_ref().to_owned();
        self
    }

    pub fn error_msg_md5<T>(mut self, msg: T) -> Self
    where
        T: AsRef<str>,
    {
        self.error_msg_md5 = msg.as_ref().to_owned();
        self
    }

    pub fn error_stack_md5<T>(mut self, md5: T) -> Self
    where
        T: AsRef<str>,
    {
        self.error_stack_md5 = md5.as_ref().to_owned();
        self
    }

    pub fn app_version<T>(mut self, version: T) -> Self
    where
        T: AsRef<str>,
    {
        self.app_version = version.as_ref().to_owned();
        self
    }

    pub fn sdk_version<T>(mut self, version: T) -> Self
    where
        T: AsRef<str>,
    {
        self.sdk_version = version.as_ref().to_owned();
        self
    }

    pub fn os_name(mut self, name: OsName) -> Self {
        self.os_name = name;
        self
    }

    pub fn client_version<T>(mut self, version: T) -> Self
    where
        T: AsRef<str>,
    {
        self.client_version = version.as_ref().to_owned();
        self
    }

    pub fn openid<T>(mut self, openid: T) -> Self
    where
        T: AsRef<str>,
    {
        self.openid = openid.as_ref().to_owned();
        self
    }

    pub fn offset(mut self, offset: u32) -> Self {
        self.offset = offset;
        self
    }

    pub fn limit(mut self, limit: u32) -> Self {
        self.limit = limit;
        self
    }

    pub fn desc(mut self, desc: Desc) -> Self {
        self.desc = desc;
        self
    }

    pub fn build(self) -> JsErrDetailReq {
        JsErrDetailReq {
            start_time: self.start_time,
            end_time: self.end_time,
            error_msg_md5: self.error_msg_md5,
            error_stack_md5: self.error_stack_md5,
            app_version: self.app_version,
            sdk_version: self.sdk_version,
            os_name: self.os_name,
            client_version: self.client_version,
            openid: self.openid,
            offset: self.offset,
            limit: self.limit,
            desc: self.desc,
        }
    }
}
